//**************************************************************************
// Copyright 2008 Peter Project (http://www.codeplex.com/peter)
//
// License : GNU General Public License (GPL)
// For full text of the license please goto:
// http://www.gnu.org/licenses/gpl-2.0.html
//
// This code is provided on an AS IS basis, with no WARRANTIES,
// CONDITIONS or GUARANTEES of any kind.
//
//		File: CustomInstall.cs
//		Purpose: This file holds all the custome methods for the
//				 Installation of Peter.
//
//**************************************************************************

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using Microsoft.Win32;
using System.Reflection;

namespace PeterCustomInstall
{
	/// <summary>
	/// This class will run with the install to do routines that the installer cannot handle...
	/// </summary>
    [RunInstaller(true)]
    public class CustomInstall : System.Configuration.Install.Installer
    {
		/// <summary>
		/// Contructor for the custom install...
		/// </summary>
        public CustomInstall ()
        {
			// Here we can do routines before the install...
            this.BeforeInstall += new System.Configuration.Install.InstallEventHandler(CustomInstall_BeforeInstall);
        }

		/// <summary>
		/// This event occurs before the install starts...
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">InstallEventArgs event data.</param>
        void CustomInstall_BeforeInstall (object sender, System.Configuration.Install.InstallEventArgs e)
        {
        }

		/// <summary>
		/// This method runs after the files are copied...
		/// </summary>
		/// <param name="stateSaver">State saver so we know what changed we did.</param>
        public override void Install (System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);

			// Get the path to the install location of Peter...
            string peterPath = Assembly.GetExecutingAssembly().Location;
            peterPath = peterPath.Substring(0, peterPath.LastIndexOf("\\") + 1) + "Peter.exe";

			// Do custom actions...
            CheckEditWithPeter(stateSaver, peterPath);
            CheckSetViewSource(stateSaver, peterPath);
        }

		/// <summary>
		/// Ask if we want to add "Edit with Peter" to the shell context menu...
		/// </summary>
		/// <param name="stateSaver">State saver so we know what changed we did.</param>
		/// <param name="peterPath">Path to the peter install.</param>
        private static void CheckEditWithPeter (System.Collections.IDictionary stateSaver, string peterPath)
        {
            if (MessageBox.Show("Would you like an \"Edit with Peter\" menu option on the Windows Explorer Context Menu?", "Peter",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                try
                {
					// Open shell reg key...
                    RegistryKey shell = Registry.ClassesRoot.OpenSubKey("*\\shell");
                    if (shell == null)
                    {
                        shell = Registry.ClassesRoot.CreateSubKey("*\\shell");
                    }

					// Create edit with peter sub key...
                    RegistryKey shellSubSub = Registry.ClassesRoot.CreateSubKey("*\\shell\\Edit with Peter\\command");
                    shellSubSub.SetValue("", peterPath + "\"%1\"");

					// Save our changes...
                    stateSaver.Add("EditAdded", true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            else
                stateSaver.Add("EditAdded", false);
        }

		/// <summary>
		/// Ask if we want Peter to be our default IE source viewer...
		/// </summary>
		/// <param name="stateSaver">State saver so we know what changed we did.</param>
		/// <param name="peterPath">Path to the peter install.</param>
        private static void CheckSetViewSource (System.Collections.IDictionary stateSaver, string peterPath)
        {
            if (MessageBox.Show("Do you want Peter to be your Default Source Viewer for Internet Explorer?", "Peter",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                try
                {
					// Open View Source Key...
                    RegistryKey source = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor\\Editor Name");
                    if (source == null)
                    {
						// The Key did not exist, we need to delete it on uninstall...
                        stateSaver.Add("deleteKey", true);
						// Create the new key...
                        source = Registry.LocalMachine.CreateSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor\\Editor Name");
                    }
                    else
                    {
						// There is already an editor, save the current editor...
                        stateSaver.Add("deleteKey", false);
                        stateSaver.Add("oldApp", source.GetValue(""));
                    }
					// Make Peter the New editor...
                    source.SetValue("", peterPath);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }

		/// <summary>
		/// This will occur when we uninstall Peter...
		/// </summary>
		/// <param name="stateSaver">State saver - gives us the changes we did on install.</param>
        public override void Uninstall (System.Collections.IDictionary savedState)
        {
            base.Uninstall(savedState);

            if (savedState.Contains("deleteKey"))
            {
                bool del = (bool)savedState["deleteKey"];
                if (del)
                {
					// Delete the view source reg key...
                    RegistryKey source = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor\\Editor Name");
                    if (source != null)
                    {
                        Registry.LocalMachine.DeleteSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor\\Editor Name");
                        Registry.LocalMachine.DeleteSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor");
                    }
                }
                else
                {
					// Change the IE view source to the old editor...
                    if (savedState.Contains("oldApp"))
                    {
                        string oldApp = savedState["oldApp"].ToString();
                        RegistryKey source = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor\\Editor Name");
                        if (source != null)
                            source.SetValue("(Default)", oldApp);
                    }
                    else
                    {
						// The old app is unknown, delete the key...
                        RegistryKey source = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor\\Editor Name");
                        if (source != null)
                        {
                            Registry.LocalMachine.DeleteSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor\\Editor Name");
                            Registry.LocalMachine.DeleteSubKey("Software\\Microsoft\\Internet Explorer\\View Source Editor");
                        }
                    }
                }
            }

			// Remove Edit with key...
            if (savedState.Contains("EditAdded"))
            {
                //Registry.ClassesRoot.DeleteSubKey("*\\shell\\Edit with Peter");
            }
        }

		/// <summary>
		/// This occurs when the install is complete...
		/// </summary>
		/// <param name="stateSaver">State saver - gives us the changes we did on install.</param>
        public override void Commit (System.Collections.IDictionary savedState)
        {
            base.Commit(savedState);
        }
		
		/// <summary>
		/// This occurs when we have to exit or roll back the install...
		/// TODO: we need to rollback changes done to the registry, if the install crashes.
		/// </summary>
		/// <param name="stateSaver">State saver - gives us the changes we did on install.</param>
        public override void Rollback (System.Collections.IDictionary savedState)
        {
            base.Rollback(savedState);
        }
    }
}
